package cn.source.web.controller.common;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import cn.source.system.common.constant.CommonConstants;
import cn.source.system.common.constant.NumberConstants;
import cn.source.system.common.exception.MisException;
import cn.source.system.config.security.CurrUserDetails;
import cn.source.system.organization.entity.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * <p>BaseController.java此类用于基础</p>
 * <p>@author:lizy</p>
 * <p>@date:2020年7月4日</p>
 * <p>@remark:</p>
 */
public class BaseController {

    private final Logger log = LoggerFactory.getLogger(this.getClass());

    /**
     * 得到request对象
     */
    public HttpServletRequest getRequest() {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        return request;
    }

    /**
     * 获取登录用户
     *
     * @return
     */
    public User getCurrentUser() {
        User user = (User) getSession().getAttribute("user");
        return user;
    }

    /**
     * 获取登录用户
     *
     * @return
     */
    public User getUser() {

        User user = new User();
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (CommonConstants.ANONYMOUS_USER.equals(principal)) {
            user = getCurrentUser();
        } else {
            CurrUserDetails currUser = (CurrUserDetails) principal;
            String username = currUser.getUsername();
            BeanUtil.copyProperties(currUser, user);
            user.setUserName(username);
        }

        return user;
    }

    /**
     * 获取登录用户id
     *
     * @return
     */
    public Integer getUserId() {
        return getUser().getUserId();
    }



    public String getPara(String name) {
        return StrUtil.trim(getRequest().getParameter(name));
    }

    public String getPara(String name, String defaultValue) {
        String result = getRequest().getParameter(name);
        return result != null && !"".equals(result) ? result : defaultValue;
    }

    private Integer toInt(String value, Integer defaultValue) {
        try {
            if (StrUtil.isBlank(value)) {
                return defaultValue;
            }

            value = value.trim();
            if (value.startsWith(CommonConstants.CAPITAL_N) || value.startsWith(CommonConstants.LOWER_CASE_N)) {
                return -Integer.parseInt(value.substring(1));
            }

            return Integer.parseInt(value);
        } catch (Exception e) {
            throw new MisException("Can not parse the parameter \"" + value + "\" to Integer value.");
        }
    }


    public Integer getParaToInt(String name) {
        return toInt(getRequest().getParameter(name), null);
    }


    public Integer getParaToInt(String name, Integer defaultValue) {
        return toInt(getRequest().getParameter(name), defaultValue);
    }

    private Long toLong(String value, Long defaultValue) {
        try {
            if (StrUtil.isBlank(value)) {
                return defaultValue;
            }

            value = value.trim();
            if (value.startsWith(CommonConstants.CAPITAL_N) || value.startsWith(CommonConstants.LOWER_CASE_N)) {
                return -Long.parseLong(value.substring(1));
            }

            return Long.parseLong(value);
        } catch (Exception e) {
            throw new MisException("Can not parse the parameter \"" + value + "\" to Long value.");
        }
    }


    public Long getParaToLong(String name) {
        return toLong(getRequest().getParameter(name), null);
    }


    public Long getParaToLong(String name, Long defaultValue) {
        return toLong(getRequest().getParameter(name), defaultValue);
    }

    private Boolean toBoolean(String value, Boolean defaultValue) {
        if (StrUtil.isBlank(value)) {
            return defaultValue;
        }
        value = value.trim().toLowerCase();
        if (CommonConstants.STRING_ONE.equals(value) || CommonConstants.FLAG_TRUE.equals(value)) {
            return Boolean.TRUE;
        } else if (CommonConstants.STRING_ZERO.equals(value) || CommonConstants.FLAG_FALSE.equals(value)) {
            return Boolean.FALSE;
        }

        throw new MisException("Can not parse the parameter \"" + value + "\" to Boolean value.");
    }

    public Boolean getParaToBoolean(String name) {
        return toBoolean(getRequest().getParameter(name), null);
    }


    public Boolean getParaToBoolean(String name, Boolean defaultValue) {
        return toBoolean(getRequest().getParameter(name), defaultValue);
    }


    public Map<String, String[]> getParaMap() {
        return getRequest().getParameterMap();
    }


    public Enumeration<String> getParaNames() {
        return getRequest().getParameterNames();
    }


    public String[] getParaValues(String name) {
        return getRequest().getParameterValues(name);
    }

    public BaseController setAttr(String name, Object value) {
        getRequest().setAttribute(name, value);
        return this;
    }

    public BaseController setAttrs(Map<String, Object> attrMap) {
        for (Map.Entry<String, Object> entry : attrMap.entrySet()) {
            getRequest().setAttribute(entry.getKey(), entry.getValue());
        }
        return this;
    }


    public BaseController removeAttr(String name) {
        getRequest().removeAttribute(name);
        return this;
    }

    public <T> T getAttr(String name) {
        return (T) getRequest().getAttribute(name);
    }

    public <T> T getAttr(String name, T defaultValue) {
        T result = (T) getRequest().getAttribute(name);
        return result != null ? result : defaultValue;
    }

    public HttpSession getSession() {
        return getRequest().getSession();
    }

    public HttpSession getSession(boolean create) {
        return getRequest().getSession(create);
    }

    public <T> T getSessionAttr(String key) {
        HttpSession session = getRequest().getSession(false);
        return session != null ? (T) session.getAttribute(key) : null;
    }

    public <T> T getSessionAttr(String key, T defaultValue) {
        T result = getSessionAttr(key);
        return result != null ? result : defaultValue;
    }

    public BaseController setSessionAttr(String key, Object value) {
        getRequest().getSession(true).setAttribute(key, value);
        return this;
    }

    public BaseController removeSessionAttr(String key) {
        HttpSession session = getRequest().getSession(false);
        if (session != null) {
            session.removeAttribute(key);
        }

        return this;
    }

    public String getIpAddr(HttpServletRequest request) {
        String ipAddress = null;
        ipAddress = request.getHeader("x-forwarded-for");
        if (ipAddress == null || ipAddress.length() == 0 || CommonConstants.REQUEST_UNKNOWN.equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getHeader("Proxy-Client-IP");
        }
        if (ipAddress == null || ipAddress.length() == 0 || CommonConstants.REQUEST_UNKNOWN.equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ipAddress == null || ipAddress.length() == 0 || CommonConstants.REQUEST_UNKNOWN.equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getRemoteAddr();
            if (CommonConstants.IP_ADDRESS_127.equals(ipAddress) || CommonConstants.IP_ADDRESS_MAC.equals(ipAddress)) {
                //根据网卡取本机配置的IP
                InetAddress inet = null;
                try {
                    inet = InetAddress.getLocalHost();
                    ipAddress = inet.getHostAddress();
                } catch (UnknownHostException e) {
                    log.error("获取主机IP错误", e);
                }

            }

        }
        //对于通过多个代理的情况，第一个IP为客户端真实IP,多个IP按照','分割
        if (ipAddress != null && ipAddress.length() > NumberConstants.NUMBER_FIFTEEN) {
            if (ipAddress.indexOf(CommonConstants.EN_PUNCTUATION_COMMA) > 0) {
                ipAddress = ipAddress.substring(0, ipAddress.indexOf(CommonConstants.EN_PUNCTUATION_COMMA));
            }
        }
        return ipAddress;
    }

    /**
     * 获取header 信息
     *
     * @return
     */
    public Map<String, String> getHeadersInfo() {
        Map<String, String> map = new HashMap<String, String>(8);
        HttpServletRequest request = getRequest();
        Enumeration headerNames = request.getHeaderNames();
        while (headerNames.hasMoreElements()) {
            String key = (String) headerNames.nextElement();
            String value = request.getHeader(key);
            map.put(key, value);
        }
        return map;
    }

    /**
     * 判断是否是谷歌浏览器
     *
     * @return
     */
    public boolean isChrome() {
        boolean isChrome = false;
        String userAgent = getRequest().getHeader("USER-AGENT");
        if (userAgent.indexOf(CommonConstants.BROWSER_OPR) > -1 && userAgent.indexOf(CommonConstants.BROWSER_CHROME) > -1 && userAgent.indexOf(CommonConstants.BROWSER_SAFARI) > -1) {
        } else if (userAgent.indexOf(CommonConstants.BROWSER_QQ_BROWSER) > -1 && userAgent.indexOf(CommonConstants.BROWSER_CHROME) > -1 && userAgent.indexOf(CommonConstants.BROWSER_SAFARI) > -1) {
        } else if (userAgent.indexOf(CommonConstants.BROWSER_EDGE) > -1 && userAgent.indexOf(CommonConstants.BROWSER_CHROME) > -1 && userAgent.indexOf(CommonConstants.BROWSER_SAFARI) > -1) {
        } else if (userAgent.indexOf(CommonConstants.BROWSER_SE) > -1 && userAgent.indexOf(CommonConstants.BROWSER_CHROME) > -1 && userAgent.indexOf(CommonConstants.BROWSER_SAFARI) > -1) {
        } else if (userAgent.indexOf(CommonConstants.BROWSER_CHROME) > -1 && userAgent.indexOf(CommonConstants.BROWSER_SAFARI) > -1) {
            isChrome = true;
        } else {
        }
        return isChrome;
    }

    /**
     * 生成唯一编码
     *
     * @return
     */
    public String getUuid() {
        UUID uuid = UUID.randomUUID();
        return uuid.toString().replace("-", "").toUpperCase();
    }
}
